﻿using System.Collections.Generic;
using Zeta;
using Zeta.CommonBot;
using Zeta.Internals.Actors;
using System.Linq;

namespace IncubusCC.Helpers
{
    internal static class Unit
    {
        /// <summary>
        /// Checks if the mob is Elite or Rare
        /// </summary>
        /// <param name="unit">DiaUnit</param>
        /// <returns>True if Current unit is Elite</returns>
        public static bool IsElite(this DiaUnit unit)
        {
            return unit.CommonData.MonsterAffixes.HasFlag(MonsterAffixes.Elite) ||
                unit.CommonData.MonsterAffixes.HasFlag(MonsterAffixes.Rare) ||
                unit.CommonData.MonsterAffixes.HasFlag(MonsterAffixes.Unique) ||
                unit.Name.StartsWith("treasureGoblin");
        }

        /// <summary>
        /// Checks if the mob is Elite or Rare && with range
        /// </summary>
        /// <param name="unit">DiaUnit</param>
        /// <param name="range">Range from us to unit</param>
        /// <returns>True if current uint is Elite && unit is in range</returns>
        public static bool IsElite(this DiaUnit unit, float range)
        {
            var targetLoc = ZetaDia.Me.Position;
            return IsElite(unit) && unit.Position.DistanceSqr(targetLoc) <= range * range;
        }

        /// <summary>
        /// Checks if any unit is elite within a set range
        /// </summary>
        /// <param name="range"></param>
        /// <returns></returns>
        public static bool IsElite(float range)
        {
            var targetLoc = ZetaDia.Me.Position;
            IEnumerable<DiaObject> units = CombatTargeting.Instance.LastObjects.Where(u => u.Position.DistanceSqr(targetLoc) <= range * range);
            return (units.Count(u => (u.CommonData.MonsterAffixes.HasFlag(MonsterAffixes.Elite) ||
                u.CommonData.MonsterAffixes.HasFlag(MonsterAffixes.Rare) || u.CommonData.MonsterAffixes.HasFlag(MonsterAffixes.Unique) ||
                u.Name.StartsWith("treasureGoblin"))) > 0);
        }

        /// <summary>
        /// Checks if we are Blind, Feared, Frozen, Stunned or Rooted
        /// </summary>
        public static bool MeIncapacited
        {
            get
            {
                var me = ZetaDia.Me;
                return me.IsFeared || me.IsStunned || me.IsFrozen || me.IsBlind || me.IsRooted;
            }
        }

        /// <summary>
        /// Gets the minions of the local player.
        /// </summary>
        /// <remarks>Created 2012-07-11</remarks>
        public static IEnumerable<DiaUnit> Minions
        {
            get
            {
                int dynId = ZetaDia.Me.CommonData.DynamicId;
                var minions = ZetaDia.Actors.GetActorsOfType<DiaUnit>().Where(u => u.CommonData != null && u.SummonedByACDId == dynId);
                return minions;
            }
        }

        /// <summary>
        /// Determines whether you have specified pet summoned.
        /// </summary>
        /// <param name="petName">Name of the pet.</param>
        /// <returns>
        ///   <c>true</c> if you have specified pet summoned; otherwise, <c>false</c>.
        /// </returns>
        /// <remarks>Created 2012-07-11</remarks>
        public static bool HasPet(string petName)
        {
            return PetCount(petName) != 0;
        }

        /// <summary>
        /// Counts how many minions with the provided name you got summoned.
        /// </summary>
        /// <param name="petName">Name of the pet.</param>
        /// <returns></returns>
        /// <remarks>Created 2012-07-11</remarks>
        public static int PetCount(string petName)
        {
            return Minions.Count(m => m.Name.Contains(petName));
        }
    }
}
